package sell

import (
	"adam2/internal/model"
	"adam2/internal/properties"
	"adam2/internal/util"
	"anubis-framework/pkg/io"
	"fmt"
	"gorm.io/gorm"
)

// 解决之前卖出失败的情况
type OptimizeResolveFailSell struct {
	db *gorm.DB
}

// 初始化
func (o *OptimizeResolveFailSell) Init(db *gorm.DB) {
	o.db = db
}

// 卖出
func (o *OptimizeResolveFailSell) DoSell(transactionDate string) {
	io.Infoln("解决之前卖出失败的情况")

	// optimize_account表的所有记录
	var optimizeAccountArray model.OptimizeAccountArray
	o.db.Table("optimize_account").Select("*").Order("id_ asc").Find(&optimizeAccountArray)

	for _, optimizeAccount := range optimizeAccountArray {
		// 如果这个账户没有持有股票，则查找下一个账户
		if optimizeAccount.HoldStockNumber == 0 {
			io.Infoln("账号[%s]持股票数量为0，不需要卖出股票", (*optimizeAccount).AccountName)
			continue
		}

		// 查询某个优化账户之前卖出失败的股票
		var optimizeStockTransactRecordArray model.OptimizeStockTransactRecordArray
		o.db.Raw("select * from optimize_stock_transact_record t "+
			"where t.account_name = ? and t.SELL_DATE is null "+
			"and t.SELL_PRICE is null and t.SELL_AMOUNT is null and t.fail_sell_reason in(1, 2)",
			optimizeAccount.AccountName).Scan(&optimizeStockTransactRecordArray)
		for _, optimizeStockTransactRecord := range optimizeStockTransactRecordArray {
			// 查询股票
			var stockTransactionDataAll model.StockTransactionDataAll
			o.db.Raw("select * from stock_transaction_data_all t "+
				"where t.code_ = ? and t.date_=to_date(?, 'yyyy-mm-dd')", optimizeStockTransactRecord.StockCode, transactionDate).Scan(&stockTransactionDataAll)

			// 如果没有查找到记录，可能是因为这个股票在这个交易日停牌，因此跳过这条记录
			if stockTransactionDataAll.ID == 0 {
				io.Infoln("股票[%s]在日期[%s]没有查找到记录，可能是因为这个股票在这个交易日停牌，因此跳过这条记录", optimizeStockTransactRecord.StockCode, transactionDate)
				continue
			}

			// 如果是一字跌停板，因此跳过这条记录
			if util.OneWordLimitDown(stockTransactionDataAll, transactionDate) {
				io.Infoln("股票[%s]在日期[%s]是一字跌停板，因此跳过这条记录", optimizeStockTransactRecord.StockCode, transactionDate)
				continue
			}

			// 卖出
			// 更新optimize_stock_transact_record表的sell_date、sell_price、sell_amount和fail_sell_reason字段
			o.db.Exec("update optimize_stock_transact_record t "+
				"set t.sell_date = to_date(?, 'yyyy-mm-dd'), t.sell_price  = ?, t.sell_amount = t.buy_amount, "+
				"t.stamp_duty = ROUND(t.buy_amount * "+fmt.Sprintf("%f", stockTransactionDataAll.OpenPrice)+" * "+fmt.Sprintf("%f", properties.QuantProperties_.StampDutyRate)+", 4), "+
				"t.registration_fee_when_sell = ?, "+
				"t.commission_when_sell = ? "+
				"where t.id_ = ?",
				transactionDate, stockTransactionDataAll.ClosePrice,
				util.CalculateRegistrationFee(optimizeStockTransactRecord.StockCode, optimizeStockTransactRecord.BuyAmount),
				util.CalculateCommission(stockTransactionDataAll.ClosePrice, optimizeStockTransactRecord.BuyAmount),
				optimizeStockTransactRecord.ID)

			// 更新quant_stock_transact_record表的profit_and_loss和profit_and_loss_rate字段
			o.db.Exec("update optimize_stock_transact_record t "+
				"set t.profit_and_loss = ROUND((t.sell_price * t.sell_amount) - (t.buy_price * t.buy_amount), 4), "+
				"t.profit_and_loss_rate = (t.sell_price - t.buy_price) / t.buy_price * 100 "+
				"where t.id_ = ?", optimizeStockTransactRecord.ID)
		}
	}
}
